.Net: Harden AllowedBaseUrls validation in RestApiOperationRunner#13910
.Net: Harden AllowedBaseUrls validation in RestApiOperationRunner#13910SergeyMenshykh wants to merge 1 commit intomicrosoft:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR tightens SSRF-related URL validation in the OpenAPI REST operation runner by enforcing path-boundary matching when comparing resolved request URLs against configured AllowedBaseUrls.
Changes:
- Hardened
RestApiOperationRunner.ValidateUrl()to avoid accidental prefix matches (e.g.,/v1matching/v1-evil). - Added unit tests to cover the prefix-collision block case and to confirm valid sub-paths remain allowed.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| dotnet/src/Functions/Functions.OpenApi/RestApiOperationRunner.cs | Updates base URL matching to require an exact match or a slash-delimited sub-path match. |
| dotnet/src/Functions/Functions.UnitTests/OpenApi/RestApiOperationRunnerTests.cs | Adds regression tests for prefix-collision and a valid /v1/* allow case. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Automated Code Review
Reviewers: 4 | Confidence: 93%
✓ Correctness
This is a well-crafted security fix for a path-prefix collision vulnerability in URL validation. The original
StartsWithcheck allowed URLs likehttps://api.example.com/v1-evilto pass validation whenhttps://api.example.com/v1was the allowed base URL. The fix normalizes the base URL to include a trailing slash before the prefix check, and adds an exact-match branch to still allow requests to the base URL itself (without a trailing slash). The two new tests correctly cover the attack scenario and the legitimate sub-path scenario. The logic is sound and I found no correctness issues.
✓ Security Reliability
This is a well-crafted security fix that closes a real URL prefix-collision vulnerability in the AllowedBaseUrls validation. Before this change,
https://api.example.com/v1-evilwould pass validation against an allowed base URL ofhttps://api.example.com/v1via naive string prefix matching. The fix normalizes the base URL to end with/before prefix comparison and adds an exact-match branch for the no-trailing-slash case. Both branches are necessary and correct. The two new tests cover the blocking and allowing scenarios precisely. No security or reliability issues found.
✓ Test Coverage
The security fix for path prefix collision is correct and the two new tests cover the primary attack vector (path-level prefix collision) and the legitimate sub-path case. However, the newly added exact-match code path (
string.Equals(urlString, baseUrl.AbsoluteUri, ...)at line 256) has no dedicated test. This branch is essential for when the request URL exactly equals the allowed base URL with no additional path (e.g., both arehttps://api.example.com/v1), since the slash-appended StartsWith check would reject it. Without a test, this branch could regress silently. Additionally, a host-level prefix collision test (e.g.,api.example.comallowed vsapi.example.com.evil.comrequested) would strengthen the security regression suite.
✗ Design Approach
The change fixes the specific
/v1vs/v1-evilcollision, but it does so with another string-prefix special case instead of validating URI components. Because the runner validates the fully built request URL after appending query parameters, the new logic will now reject legitimate requests to the exact allowed resource when that resource has a query string (for examplehttps://api.example.com/v1?foo=bar). That makes the approach too narrow for the contract this option is meant to enforce.
Suggestions
- Consider adding a host-level prefix collision test where the allowed base URL is
https://api.example.comand the malicious server ishttps://api.example.com.evil.com. WhileUri.AbsoluteUrinormalization currently protects against this, an explicit test would guard against future regressions. - Add a regression test for an allowed base URL used as the exact resource with query parameters (e.g., allowed base
https://api.example.com/v1, requesthttps://api.example.com/v1?user=1) to exercise validation against the URL shape thatBuildsOperationUrlactually produces.
Automated review by SergeyMenshykh's agents
9627892 to
3711a8b
Compare
Strengthened base URL comparison in ValidateUrl to enforce proper path-boundary matching when checking request URLs against configured AllowedBaseUrls, and added unit tests for the stricter validation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
3711a8b to
b8b3775
Compare
Motivation and Context
Improved the URL validation logic in
RestApiOperationRunner.ValidateUrl()to ensure stricter matching when checking request URLs against configuredAllowedBaseUrls. The previous implementation could match unintended URLs in certain edge cases involving path-prefixed base URLs.Description
Strengthened the base URL comparison to enforce proper path-boundary matching, preventing URLs outside the intended allowed scope from passing validation.
Changes
RestApiOperationRunner.cs: Tightened the base URL matching logic inValidateUrlto enforce path-boundary alignment.RestApiOperationRunnerTests.cs: Added two new tests to verify the stricter validation behavior and confirm legitimate sub-paths remain allowed.Risk
Low — the fix tightens existing validation without changing the public API surface. All URL validation tests pass.